package entity

import (
	"context"
	"encoding/json"
	"github.com/pkg/errors"
	"github.com/spf13/cast"
	"nearby/biz/common"
	"nearby/biz/config"
	"nearby/biz/dal/db/po"
	"nearby/biz/dal/db/repo"
	"nearby/biz/model/vo"
	"nearby/biz/util"
	"time"
)

type CommentContent struct {
	Text string `json:"text"`
}

type Comment struct {
	CommentID    int64          `json:"comment_id"`    // 评论id
	User         User           `json:"user"`          // (创建者)用户信息
	EntityID     int64          `json:"entity_id"`     // 被评论的实体id
	EntityType   string         `json:"entity_type"`   // 被评论的实体类型, 枚举值, "评论": comment; "动态": moment
	Content      CommentContent `json:"content"`       // 评论内容
	LikeCount    int64          `json:"like_count"`    // 点赞数量
	CommentCount int64          `json:"comment_count"` // 评论数量
	CreateAt     time.Time      `json:"create_at"`     // 创建时间
}

func (c *Comment) GetUserID() int64 {
	return c.User.UserID
}

func (c *Comment) Persist(ctx context.Context) error {
	commentRepo := repo.NewCommentRepo(ctx)
	commentPo, err := commentRepo.CreateComment(ctx, c.ToPo())
	if err != nil {
		return err
	}
	c.CreateAt = commentPo.CreatedAt
	return nil
}

func (c *Comment) ToPo() po.Comment {
	j, _ := json.Marshal(c.Content)
	return po.Comment{
		CommentID:    c.CommentID,
		UserID:       c.User.UserID,
		EntityID:     c.EntityID,
		EntityType:   c.EntityType,
		Content:      j,
		LikeCount:    c.LikeCount,
		CommentCount: c.CommentCount,
	}
}

func (c *Comment) ToVo() *vo.Comment {
	return &vo.Comment{
		CommentID:  cast.ToString(c.CommentID),
		EntityType: c.EntityType,
		EntityID:   cast.ToString(c.EntityID),
		UserID:     cast.ToString(c.User.UserID),
		Nickname:   c.User.Nickname,
		HeadURL:    c.User.HeadURL,
		Content: vo.CommentContent{
			Text: c.Content.Text,
		},
		LikeCount:    c.LikeCount,
		CommentCount: c.CommentCount,
		CreateAt:     util.ToTimeString(c.CreateAt),
	}
}

func (c *Comment) SetCommentID() {
	c.CommentID = config.GenerateIDInt64()
}

func (c *Comment) SyncCnt(ctx context.Context, bias int) error {
	switch c.EntityType {
	case common.EntityTypeMoment:
		return c.SyncMoment(ctx, bias)
	case common.EntityTypeComment:
		return c.SyncComment(ctx, bias)
	default:
		return errors.New("未知的实体类型")
	}
}

func (c *Comment) SyncComment(ctx context.Context, bias int) error {
	commentRepo := repo.NewCommentRepo(ctx)
	return commentRepo.UpdateCommentCnt(ctx, c.EntityID, &bias)
}

func (c *Comment) SyncMoment(ctx context.Context, bias int) error {
	momentRepo := repo.NewMomentRepo(ctx)
	return momentRepo.UpdateCommentCnt(ctx, c.EntityID, &bias)
}
